home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / daemons / init / failinit.20 / failinit / failinit1.20 / failinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-23  |  2.5 KB  |  172 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5.  
  6. #include <sys/wait.h>
  7.  
  8. #define    VERSION    "VH1.20"
  9.  
  10. #ifndef    TTY
  11. #define    TTY    "/dev/tty1"
  12. #endif
  13.  
  14. #ifndef    SHELL
  15. #define    SHELL    "/bin/sh"
  16. #endif
  17.  
  18. #ifndef    SASH
  19. #define    SASH    "/sbin/sash:/bin/sash:/etc/sash"
  20. #endif
  21.  
  22. #ifndef    INIT
  23. #define    INIT    "/bin/init:/sbin/init"
  24. #endif
  25.  
  26. static void
  27. put(const char *s)
  28. {
  29.   static int    in_line=0;
  30.  
  31.   for (; *s; putc(*s++, stderr))
  32.     if (*s=='\n')
  33.       {
  34.     putc('\r', stderr);
  35.     in_line    = 0;
  36.       }
  37.     else if (!in_line)
  38.       {
  39.     in_line    = 1;
  40.     put("failinit " VERSION ": ");
  41.       }
  42. }
  43.  
  44. static void
  45. start(const char *shells, char * const *argv)
  46. {
  47.   char        name[100];
  48.   const char    *ptr;
  49.  
  50.   for (ptr=shells;;)
  51.     {
  52.       int    i;
  53.  
  54.       for (i=0; i<sizeof name-1 && *ptr; i++)
  55.     if ((name[i]= *ptr++)==':')
  56.       break;
  57.       if (!i)
  58.     break;
  59.       name[i]    = 0;
  60.       if (argv)
  61.     execv(name, argv);
  62.       else
  63.     {
  64.       while (--i>=0 && name[i-1]!='/');
  65.       execl(name, name+i, NULL);
  66.     }
  67.     }
  68.   perror(shells);
  69. }
  70.  
  71. static int
  72. shell(const char *tty)
  73. {
  74.   if (tty)
  75.     {
  76.       close(0);
  77.       close(1);
  78.       close(2);
  79.       setsid();
  80.       if (open(tty,O_RDWR,0))
  81.     {
  82.       perror(tty);
  83.       exit(-2);
  84.     }
  85.       dup(0);
  86.       dup(0);
  87.     }
  88.   start(SASH, NULL);
  89.   start(SHELL, NULL);
  90.   exit(-1);
  91. }
  92.  
  93. static void
  94. waiter(int pid)
  95. {
  96.   do
  97.     sync();
  98.   while (wait(NULL)!=pid);
  99.   sync();
  100. }
  101.  
  102. static void
  103. fail_shell(int stop)
  104. {
  105.   int    i;
  106.  
  107.   put("\nforking fail shell ");
  108.   put(stop ? "to " TTY : "in background");
  109.   put(" ...\n");
  110.   if ((i=fork())==0)
  111.     shell(stop ? TTY : NULL);
  112.   if (stop && i>=0)
  113.     {
  114.       waiter(i);
  115.       put("\nfail shell terminated, proceeding with normal startup ...\n");
  116.     }
  117. }
  118.  
  119. static void
  120. emergency_shell(void)
  121. {
  122.   int    i, fail;
  123.  
  124.   put("\ninit not found ... spawning emergency shell (like in 1.1.82)\n");
  125.   fail    = 0;
  126.   for (;;)
  127.     if ((i=fork())==0)
  128.       shell(TTY);
  129.     else if (i<0)
  130.       {
  131.     if (!fail)
  132.       put("cannot fork() !!! sleeping ...\n");
  133.     fail    = 1;
  134.     sleep(1);
  135.       }
  136.     else
  137.       {
  138.     if (fail)
  139.       put("OK, fork() is back again\n");
  140.     fail    = 0;
  141.     waiter(i);
  142.     put("emergency shell terminated.\n");
  143.     sleep(1);
  144.       }
  145. }
  146.  
  147. int
  148. main(int argc, char **argv)
  149. {
  150.   int    i;
  151.  
  152.   if (argv[1] && !strncmp(argv[1], "fail", 4))
  153.     {
  154.       fail_shell(argv[1][4]);
  155.       for (i=1; (argv[i]=argv[i+1])!=0; i++);
  156.     }
  157.   if (argv[1])
  158.     {
  159.       put("\narguments passed to init:\n");
  160.       for (i=1; argv[i]; i++)
  161.     {
  162.       put("\t\'");
  163.       put(argv[i]);
  164.       put("\'\n");
  165.     }
  166.       put("\n");
  167.     }
  168.   start(INIT, argv);
  169.   emergency_shell();
  170.   return -1;
  171. }
  172.